package com.study.quiz.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.study.quiz.dto.CommentResponseDTO;
import com.study.quiz.enums.CommentTypeEnum;
import com.study.quiz.enums.NotifictionEnum;
import com.study.quiz.enums.NotifictionStatusEnum;
import com.study.quiz.mapper.CommentMapper;
import com.study.quiz.pojo.Comment;
import com.study.quiz.pojo.Notification;
import com.study.quiz.pojo.Question;
import com.study.quiz.pojo.User;
import com.study.quiz.service.CommentService;
import com.study.quiz.service.NotifictionService;
import com.study.quiz.service.QuestionService;
import com.study.quiz.service.UserService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author CJunGod
 * @create 2020-03-08 22:11
 **/
@Slf4j
@Service
@Transactional
public class CommentServiceImpl implements CommentService {

    @Resource
    private CommentMapper commentMapper;

    @Resource
    private QuestionService questionService;

    @Resource
    private UserService userService;

    @Resource
    private NotifictionService notifictionService;

    @Override
    public int insert(Comment comment, User user, Long questionId) {
        Question question = questionService.findByQuestionId(questionId.intValue());
        if (question != null) {
            if (comment.getType() == CommentTypeEnum.COMMENT.getType()) {
                Comment byId = commentMapper.selectById(comment.getParentId());
                commentMapper.insert(comment);
                commentMapper.updateComment(comment.getParentId(), System.currentTimeMillis());
                createNotifi(comment, byId.getParentId().longValue(), NotifictionEnum.REPLY_COMMENT, user.getName(),
                        question.getQuestionTitle(), questionId);
                return 1;
            } else {

                createNotifi(comment, question.getCreator().longValue(), NotifictionEnum.REPLY_QUESTION, user.getName(),
                        question.getQuestionTitle(), questionId);
                questionService.updateComment(question.getId(), System.currentTimeMillis());
                commentMapper.insert(comment);
                return 1;
            }
        }
        return 0;
    }

    private void createNotifi(Comment comment, Long receiverId, NotifictionEnum notifictionEnum, String notifierName, String outerTitle,
                              Long outerId) {
        Notification notification = new Notification();
        notification.setGmtCreate(System.currentTimeMillis());
        notification.setType(notifictionEnum.getType());
        notification.setOuterId(outerId);
        notification.setNotifier(receiverId);
        notification.setStatus(NotifictionStatusEnum.UNREAD.getStatus());
        notification.setReceiver(comment.getCommentator().longValue());
        notification.setNotifierName(notifierName);
        notification.setOuterTitle(outerTitle);
        notifictionService.insert(notification);
    }

    @Override
    public List<CommentResponseDTO> listByTargetId(Integer questionId, Integer type) {
        List<Comment> comments = commentMapper.selectList(new QueryWrapper<Comment>()
                .eq("parent_id", questionId)
                .eq("type", type)
                .orderByDesc("gmt_create"));
        if (comments.size() == 0) {
            return new ArrayList<>();
        }
        Set<Integer> commentators = comments.stream().map(comment -> comment.getCommentator()).collect(Collectors.toSet());
        List<User> users = userService.selectIds(commentators);
        Map<Integer, User> collect = users.stream().collect(Collectors.toMap(u -> u.getId(), u -> u));

        List<CommentResponseDTO> commentResponse = comments.stream().map(c -> {
            CommentResponseDTO commentResponseDTO = new CommentResponseDTO();
            commentResponseDTO.setComment(c);
            commentResponseDTO.setUser(collect.get(c.getCommentator()));
            return commentResponseDTO;
        }).collect(Collectors.toList());

        return commentResponse;
    }
}
